package com.mvp.lt.airlineview;

import android.graphics.Point;
import android.util.Log;

import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.MapView;
import com.amap.api.maps.Projection;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;



public class MyMapTool {


    public static void e(String msg){
        Log.e("aivin----------" ,msg) ;
    }


    /**
     * 得到 中点 - 西北 - 东北 - 东南 - 西南 个点 - 外接矩形
     * */
    public static List<LatLng> createPolygonBounds(List<LatLng> latLngList) {
        List<LatLng> latLngSparseArray = new ArrayList<>();

        if (latLngList.size() < 1) {
            return latLngSparseArray;
        }
        List<Double> latsLists = new ArrayList<>();//纬度
        List<Double> lngsLists = new ArrayList<>();//经度
        for (LatLng latLng :   latLngList) {
            latsLists.add(latLng.latitude);
            lngsLists.add(latLng.longitude);
        }
        double lngsMax = Collections.max(lngsLists); //最东经
        double latsMax = Collections.max(latsLists); //最北纬
        double latsMin = Collections.min(latsLists); //最南纬
        double lngsMin = Collections.min(lngsLists); //最西经
        double lngsCenter = (lngsMax + lngsMin) / 2;
        double latsCenter = (latsMax + latsMin) / 2;

        latLngSparseArray.add(new LatLng(latsCenter, lngsCenter));//0中点
        latLngSparseArray.add(new LatLng(latsMax, lngsMin));      //1西北
        latLngSparseArray.add(new LatLng(latsMax, lngsMax));      //2东北
        latLngSparseArray.add(new LatLng(latsMin, lngsMax));      //3东南
        latLngSparseArray.add(new LatLng(latsMin, lngsMin));      //4西南
        return latLngSparseArray;
    }


    /**
     * 无人机航线规划 ，基于凸多边形地块往复式运动  。
     * 凹多边形 有时会出现不能完全覆盖的情况 。 一般处理方法就是将 一个 凹多边形 切割成多个 凸多边形 。
     * https://www.jianshu.com/p/015dd5b53263?from=singlemessage
     */
    public static List<LatLng> createRotatePolygon(List<LatLng> mLatlists, LatLng center, int rotate) {
        List<LatLng> latLngList = new ArrayList<>();

        for (LatLng latLng : mLatlists) {
            LatLng tr = transform(
                    latLng.longitude,
                    latLng.latitude,
                    center.longitude,
                    center.latitude,
                    rotate,
                    0,
                    0
            );
            latLngList.add(tr);
        }
        return latLngList;
    }


    private static LatLng transform(double x, double y, double tx, double ty, int deg, int sx, int sy) {
        Double[] doubles = new Double[2];
        double sdeg = deg * Math.PI / 180;
        if (sy == 0) sy = 1;
        if (sx == 0) sx = 1;
        doubles[0] = sx * ((x - tx) * Math.cos(sdeg) - (y - ty) * Math.sin(sdeg)) + tx;
        doubles[1] = sy * ((x - tx) * Math.sin(sdeg) + (y - ty) * Math.cos(sdeg)) + ty;
        LatLng latLng = new LatLng(doubles[1], doubles[0]);
        return latLng;
    }





    public static List<LatLng> getLatLngByOffset(AMap aMap, List<LatLng> list, float offsetx, float offsety){
        Projection projection = aMap.getProjection();
        for(int i=0;i<list.size();i++){
            Point tempPoint = projection.toScreenLocation(list.get(i));
            tempPoint.offset((int)offsetx,(int)offsety);
            list.set(i,projection.fromScreenLocation(tempPoint));
        }
        return list;
    }





    /**计算纬度线 与边缘线的交点*/
    public static LatLng createInlinePoint(LatLng latLng1, LatLng latLng2, double y) {
        LatLng latLng;
        double s = latLng1.latitude - latLng2.latitude;
        double x;
        if (s > 0 || s < 0) {
            x = (y - latLng1.latitude) * (latLng1.longitude - latLng2.longitude) / s + latLng1.longitude;
        } else {
            return null;
        }

        /**判断x是否在p1,p2在x轴的投影里，不是的话返回null*/
        if (x > latLng1.longitude && x > latLng2.longitude) {
            return null;
        }
        if (x < latLng1.longitude && x < latLng2.longitude) {
            return null;
        }
        latLng = new LatLng(y, x);
        return latLng;
    }


    /**计算有多少条纬度线穿过 纬度线相差lat*/
    public static Double[] createLats(List<LatLng> bounds, int space) {
        Double[] integers = new Double[2];
        //线条数量
        double steps = (distance(bounds.get(1), bounds.get(4)) / space);
        //纬度差
        double lat = (bounds.get(1).latitude - bounds.get(4).latitude) / steps;
        integers[0] = steps;
        integers[1] = lat;
        return integers;
    }




    public static int sint(int i, int len) {
        if (i > len - 1) {
            return i - len;
        }
        if (i < 0) {
            return len + i;
        }
        return i;
    }



    /**计算两个点的距离*/
    public static float distance(LatLng latLng1, LatLng latLng2) {
        return AMapUtils.calculateLineDistance(latLng1, latLng2);
    }

    /**
     * 求两个经纬度的中点
     */
    public static LatLng getMidLatLng(LatLng l1, LatLng l2) {
        return new LatLng((l1.latitude + l2.latitude) / 2, (l1.longitude + l2.longitude) / 2);
    }




    /**
     *  设置经纬度转换成页面像素坐标的方法
     */
    public static Point latlng2px(AMap aMap, LatLng latlng) {
        return aMap.getProjection().toScreenLocation(latlng);
    }


    /**点到直线的距离*/
    public static double PointToSegDist(double x, double y, double x1, double y1, double x2, double y2) {
        double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
        if (cross <= 0) return Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
        double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
        if (cross >= d2) return Math.sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
        double r = cross / d2;
        double px = x1 + (x2 - x1) * r;
        double py = y1 + (y2 - y1) * r;
        return Math.sqrt((x - px) * (x - px) + (py - y) * (py - y));

    }



    /**计算两条线是否相交*/
    public static boolean doIntersect(Point p1, Point q1, Point p2, Point q2) {
        int o1 = orientation(p1, q1, p2);
        int o2 = orientation(p1, q1, q2);
        int o3 = orientation(p2, q2, p1);
        int o4 = orientation(p2, q2, q1);
        // General case
        if (o1 != o2 && o3 != o4) return true;
        if (o1 == 0 && onSegment(p1, p2, q1)) return true;
        // p1, q1 and p2 are colinear and q2 lies on segment p1q1
        if (o2 == 0 && onSegment(p1, q2, q1)) return true;
        // p2, q2 and p1 are colinear and p1 lies on segment p2q2
        if (o3 == 0 && onSegment(p2, p1, q2)) return true;
        // p2, q2 and q1 are colinear and q1 lies on segment p2q2
        if (o4 == 0 && onSegment(p2, q1, q2)) return true;
        return false;
    }


    /**
     * @return 0 --> p, q and r are colinear, 1 --> 顺时针方向, 2 --> 逆时钟方向
     */
    private static int orientation(Point p, Point q, Point r) {
        int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
        if (val == 0) return 0;  // colinear
        return (val > 0) ? 1 : 2; // clock or counterclock wise
    }



    private static boolean onSegment(Point p, Point q, Point r) {
        if (q.x <= Math.max(p.x, r.x)
                && q.x >= Math.min(p.x, r.x)
                && q.y <= Math.max(p.y, r.y)
                && q.y >= Math.min(p.y, r.y))
            return true;
        return false;
    }



}
